<?php


namespace WenRuns\Laravel\Admin\Form\Field\MultiList;


use Encore\Admin\Facades\Admin;

class AddEvent
{
    protected static $tableListParentColumns = [];

    protected static $eventsTableLists = [];

    protected static $replaceStrings = [];

    public static $registerMultiList = [];

    public static $oneRows = [];


    public static function addReplaceString($string)
    {
        if (!in_array($string, self::$replaceStrings)) {
            self::$replaceStrings[] = $string;
        }
    }


    public static function add(TableList $tableList)
    {
        $preg = '/' . MultiList::SYMBOL_BEGIN . '[\s\S]*?' . MultiList::SYMBOL_END . '/';
        $isEmpty = preg_match($preg, $tableList->parentColumn);
        if (!in_array($tableList->parentColumn, self::$tableListParentColumns) && !$isEmpty) {
            self::$eventsTableLists[] = $tableList;
            self::$tableListParentColumns[] = $tableList->parentColumn;
        } else {
            list($oneRowHtml, $oneRowScript) = self::getOneRow($tableList);
            self::register($tableList, $oneRowHtml, $oneRowScript);
        }
    }


    public static function registerEvent(MultiList $multiList)
    {
        self::$registerMultiList[] = $multiList->getUniqueKey();
        if (empty(self::$eventsTableLists)) {
            $tableList = $multiList->getTableList();
        } else {
            $tableList = array_pop(self::$eventsTableLists);
        }
        if ($tableList) {
            list($onwRowHtml, $oneRowScript) = self::getOneRow($tableList);
            self::register($tableList, $onwRowHtml, $oneRowScript, $multiList);
        }
    }


    public static function getOneRow(TableList $tableList)
    {
        $oneRows = self::$oneRows[$tableList->parentColumn] ?? null;
        if (empty($oneRows)) {
            $value = $tableList->multiList->value();
            if (isset($value[0])) {
                $value = $value[0];
            }
            $oneRow = $tableList->value($value)
                ->keyIsVariable(true)
                ->createEmpty(true)
                ->tableListBody();//->getOneRowHtml()
            $oneRow = str_replace('</', '<\/', $oneRow);
            $script = str_replace('</', '<\/', TableList::$scripts[$tableList->getTableKey() . '_oneRow'] ?? '');
            self::$oneRows[$tableList->parentColumn] = [
                'oneRow' => $oneRow,
                'script' => $script,
            ];
        } else {
            $oneRow = $oneRows['oneRow'];
            $script = $oneRows['script'];
        }
        return [
            $oneRow,
            $script,
        ];
    }

    public static function register(TableList $tableList, $oneRowHtml, $oneRowScript, MultiList $multiList = null)
    {
        $eventClosure = empty($tableList->buttonEventClosure) ? 0 : $tableList->buttonEventClosure;
        $btnClass = 'table-list-btn-add-' . $tableList->getUniqueKey();
        $replaceStr = MultiList::SYMBOL_BEGIN . $tableList->getKeyVariableName() . MultiList::SYMBOL_END;
        $replaceString = self::$replaceStrings;
        $tableKey = $tableList->getTableKey();
        $replaceString = json_encode($replaceString);
        $options = [];
        if ($multiList) {
            $options = $multiList->getOptions();
        }
        $options = json_encode($options, JSON_UNESCAPED_UNICODE);
        $script = <<<SCRIPT
$(function(){
    var appendTr = function(tableElement, num){
        let replaceString = {$replaceString};
        let oneRowHtml = `{$oneRowHtml}`.replace(/{$replaceStr}/mg, num);
        let script = `{$oneRowScript}`.replace(/{$replaceStr}/mg, num);
        let trEle = null;
        let res = checkOneRowHtml(tableElement, oneRowHtml, script);
        oneRowHtml = res.oneRowHtml;
        script = res.script;
        replaceString.forEach((str, i)=>{
            eval("var reg = /"+str+"/mg")
            oneRowHtml = oneRowHtml.replace(reg, 0);
            script = script.replace(reg, 0);
        });
        // table元素下有thead 和 tbody 两个子元素
        Array.from(tableElement.children).forEach(function(item, k){
            if(item.tagName == 'TBODY'){  // 判断为tbody子元素
                if(item.dataset.empty){ // 判断是否为空表格
                    item.innerHTML = "";
                    item.removeAttribute("data-empty")
                }
                var table = document.createElement("table");
                table.innerHTML = oneRowHtml;
                function addTd(tr){
                    trEle = tr;
                    if("{$tableList->enableInsertEleAfterActive}"){
                        let activeObj = item.querySelector("tr.active-tr");
                        if(activeObj){
                            $(tr).insertAfter(activeObj);
                        }else{
                            item.append(tr);
                        }
                    }else{
                        item.append(tr);
                    }

                    if(script){
                        eval(script);
                    }
                }
                Array.from(table.children).forEach(function(child){
                    if(child.tagName == "TBODY"){
                        Array.from(child.children).forEach(function(vo){
                            addTd(vo);
                        });
                    }else if(child.tagName == "TR"){
                        addTd(child);
                    }
                });
            }
        });
        return trEle;
    }

    var checkOneRowHtml = function(tableEle, oneRowHtml, script){
        if(tableEle.dataset.sub == 'true'){
            let parentTrEle = tableEle.parentElement;
            while(parentTrEle.tagName != 'TR'){
                parentTrEle = parentTrEle.parentElement;
            }
            let trEle = parentTrEle.previousElementSibling,
                num = trEle.dataset.col,
                replaceStr = trEle.dataset.begin+trEle.dataset.key+trEle.dataset.end;
            eval("var reg = /" + replaceStr + "/mg");
            oneRowHtml = oneRowHtml.replace(reg, num);
            script = script.replace(reg, num);
            checkOneRowHtml(trEle.parentElement.parentElement, oneRowHtml, script);
        }
        return {
            oneRowHtml,
            script,
        };
    }

    if("{$tableList->enableInsertEleAfterActive}"){
        $(document).on("click", "#{$tableKey} tbody .{$tableKey}-tr", function(e){
            let parentEle = e.currentTarget.parentElement;
            if(parentEle){
                let activeObj = parentEle.querySelector("tr.active-tr");
                if(activeObj){
                    activeObj.classList.remove('active-tr');
                }
            }
            e.currentTarget.classList.add('active-tr');
        });
        $(document).click(function(e){
            let obj = e.target.querySelector("#{$tableKey} tbody");
            if(obj){
                let activeObj = obj.querySelector("tr.active-tr");
                if(activeObj){
                    activeObj.classList.remove("active-tr");
                }
            }
        });
    }
    $(document).on("click", "#{$tableKey} .{$btnClass}", function(e){
        var appendContent = function(){
            let tableElement = e.currentTarget.parentElement.parentElement.parentElement.parentElement;
            let num = e.currentTarget.dataset.number;
            return appendTr(tableElement, num);
        }
        var fn = {$eventClosure};
        if(fn){
            fn.call(this, e, appendContent);
        }else{
            appendContent();
        }
        e.currentTarget.dataset.number++;
    });
});
SCRIPT;
        Admin::script($script);
    }
}
